import type { Request } from 'express';

import {
  ClassSerializerInterceptor,
  Module,
  MiddlewareConsumer,
  RequestMethod,
  ExecutionContext,
} from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';

import { APP_FILTER, APP_GUARD, APP_INTERCEPTOR } from '@nestjs/core';
import { ThrottlerGuard } from '@nestjs/throttler';
import { ClsModule } from 'nestjs-cls';

import config from '~/config';
import { SharedModule } from '~/shared/shared.module';

import { AllExceptionsFilter } from './common/filters/any-exception.filter';
import { LoggingInterceptor } from './common/interceptors/logging.interceptor';

import { IdempotenceInterceptor } from './common/interceptors/idempotence.interceptor';
import { TimeoutInterceptor } from './common/interceptors/timeout.interceptor';
import { TransformInterceptor } from './common/interceptors/transform.interceptor';
import { AuthModule } from './modules/auth/auth.module';
import { JwtAuthGuard } from './modules/auth/guards/jwt-auth.guard';
import { RbacGuard } from './modules/auth/guards/rbac.guard';
import { SseModule } from './modules/sse/sse.module';
import { SystemModule } from './modules/system/system.module';
import { TasksModule } from './modules/tasks/tasks.module';
import { TodoModule } from './modules/todo/todo.module';
import { ToolsModule } from './modules/tools/tools.module';
import { MinioModule } from './shared/minio/minio.modules';

//两个数据库查询关联
import { DataBaseLinkModule } from './shared/databaselink/databaselink.modules';

//具体的业务模块
import { BusinessModule } from './modules/bussiness/bussiness.module';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      expandVariables: true,
      // 指定多个 env 文件时，第一个优先级最高
      envFilePath: ['.env.local', `.env.${process.env.NODE_ENV}`, '.env'],
      load: [...Object.values(config)],
    }),
    // 启用 CLS 上下文
    ClsModule.forRoot({
      global: true,
      interceptor: {
        mount: true,
        setup: (cls, context: ExecutionContext) => {
          const req = context.switchToHttp().getRequest<Request>(); // 使用 Express Request
          if (req.params?.id && req.body) {
            cls.set('operateId', Number.parseInt(req.params.id));
          }
        },
      },
    }),
    //基础依赖模块
    SharedModule,

    //基础业务模块
    AuthModule,
    TasksModule.forRoot(),
    SystemModule,
    SseModule,
    MinioModule,
    ToolsModule,
    DataBaseLinkModule,
    TodoModule,

    //具体业务模块
    BusinessModule,
  ],
  providers: [
    //自定义异常过滤器
    { provide: APP_FILTER, useClass: AllExceptionsFilter },
    // 自定义响应拦截器
    { provide: APP_INTERCEPTOR, useClass: TransformInterceptor },
    //全局请求超时拦截器
    {
      provide: APP_INTERCEPTOR,
      useFactory: () => new TimeoutInterceptor(15 * 1000),
    },
    //请求日志拦截
    { provide: APP_INTERCEPTOR, useClass: LoggingInterceptor },
    //全局幂等性拦截器，防止重复提交请求
    { provide: APP_INTERCEPTOR, useClass: IdempotenceInterceptor },
    //JWT验证
    { provide: APP_GUARD, useClass: JwtAuthGuard },
    //接口权限控制
    { provide: APP_GUARD, useClass: RbacGuard },
    //启用请求频率限制守卫
    // { provide: APP_GUARD, useClass: ThrottlerGuard },
  ],
})
export class AppModule {}
